﻿// -----------------------------------------------------------------------
// <copyright file="BattleField.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Cspl.AnimalFight.Lib
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Cspl.AnimalFight.Lib.Data;
    using Cspl.AnimalFight.Lib.EventHandlers;
    using Cspl.AnimalFight.Lib.Interfaces;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class BattleField
    {
        private IList<AnimalBase> _animalList;

        public BattleField()
        {
            this._animalList = new List<AnimalBase>();
        }

        public IList<AnimalBase> AnimalList
        {
            get { return _animalList; }
            private set { _animalList = value; }
        }

        public AnimalBase this[string name]
        {
            get { return this._animalList.FirstOrDefault(a => a.Name == name); }
            set
            {
                if (value != null)
                {
                    IAttack attackingAnimal = value as IAttack;
                    if (attackingAnimal != null)
                    {
                        attackingAnimal.AttackEvent += new AttackDelegate(attackingAnimal_AttackEvent);
                    }

                    IDefend defendingAnimal = value as IDefend;
                    if (defendingAnimal != null)
                    {
                        defendingAnimal.DefendEvent += new DefendDelegate(defendingAnimal_DefendEvent);
                    }

                    this._animalList.Add(value);
                }
            }
        }

        public struct NewAnimal
        {
            public Animals type;
            public string name;
            public int HP, DP, AP;
            public DogMood mood;
        }

        private void defendingAnimal_DefendEvent(object sender, DefendEventHandler e)
        {
            var defendingAnimal = this[e.AnimalName];

            if (defendingAnimal != null)
            {
                IDefend theAnimal = defendingAnimal as IDefend;
                if (theAnimal != null)
                {
                    theAnimal.IsDefending = true;
                }
                else
                {
                    Console.WriteLine("The animal {0} cannot defend itself.", e.AnimalName);
                }
            }
        }

        private void attackingAnimal_AttackEvent(object sender, AttackEventHandler e)
        {
            var animalTarget = this[e.AnimalTargetName];

            if (animalTarget != null)
            {
                IAttackable attackedAnimal = animalTarget as IAttackable;
                if (attackedAnimal != null)
                {
                    Console.WriteLine("{0} is attacked with AP={1}.", e.AnimalTargetName, e.AP);
                    attackedAnimal.Attacked(e.AP);
                }
                else
                {
                    Console.WriteLine("The animal {0} is immortal.", e.AnimalTargetName);
                }
            }
        }

        public void Command(string animalName, Commands command, string targetName)
        {
            Console.WriteLine("\nBattle Information");
            Console.WriteLine("------------------");
            var animal = this[animalName];
            if (animal != null)
            {
                if (animalName.Equals(targetName))
                {
                    Console.WriteLine("{0} cannot fight itself", animalName);
                }
                else
                {
                    switch (command)
                    {
                        case Commands.Attack:
                            if (animal is IAttack)
                            {
                                (animal as IAttack).Attack(targetName);
                            }
                            else
                            {
                                Console.WriteLine("Animal {0} cannot attack.", animalName);
                            }
                            break;
                        case Commands.Defend:
                            if (animal is IDefend)
                            {
                                (animal as IDefend).Defend();
                            }
                            else
                            {
                                Console.WriteLine("Animal {0} cannot defend.", animalName);
                            }
                            break;
                        case Commands.Escape:
                            animal.Escape();
                            break;
                        case Commands.Enter:
                            animal.Enter();
                            break;
                        case Commands.Eat:
                            if (!animal.IsDead)
                            {
                                if (this[targetName].IsDead)
                                {
                                    Console.WriteLine("Animal {0} is eaten by {1}. {0} is gone T_T.", targetName, animalName);
                                    this.DeleteAnimal(targetName);
                                }
                                else
                                {
                                    Console.WriteLine("Animal {0} is still alive. Cannot be eaten.", targetName);
                                }
                            }
                            else
                            {
                                Console.WriteLine("Animal {0} has already died cannot eat another animals.", animalName);
                            }
                            break;
                    }
                    ShowDetailAnimals(animal, this[targetName]);
                }

            }
            else
            {
                Console.WriteLine("Animal {0} is not exists.", animalName);
            }
        }

        public void ShowDetailAnimals(AnimalBase currentAttacker, AnimalBase currentTarget)
        {
            Console.WriteLine("\nCurrent Animal Information");
            Console.WriteLine("--------------------------");
            foreach (AnimalBase animal in AnimalList)
            {
                Console.WriteLine("\nName : {0}", animal.Name);
                if (animal.Equals(currentAttacker) || animal.Equals(currentTarget))
                {
                    Console.WriteLine("Attack Power : {0}", animal.AP);
                    Console.WriteLine("Defend Power : {0}", animal.DP);
                    Console.WriteLine("Health Power : {0}", animal.HP);

                }
                if (animal.HasEscaped)
                {
                    Console.WriteLine("Status : Has Escaped");
                }
                else if (animal.IsDead)
                {
                    Console.WriteLine("Status : Died");
                }
            }
        }

        //remove animal from AnimalList
        public void DeleteAnimal(string animalName)
        {
            this.AnimalList.Remove(this[animalName]);
        }
    }

    public enum Commands { Attack, Defend, Escape, Enter, Eat }
}
